package com.doubao.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Collections;
import java.util.Set;
import java.util.function.Consumer;

/**
 * 请求日志过滤器
 */
@Slf4j
@Component
public class RequestLogFilter implements GlobalFilter, Ordered {

    private static final Set<String> SENSITIVE_HEADERS =
            Collections.singleton("Authorization");

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        URI uri = request.getURI();
        String path = uri.getPath();
        String method = request.getMethod().name();
        String remoteAddress = request.getRemoteAddress().getAddress().getHostAddress();

        // 记录请求开始
        long startTime = System.currentTimeMillis();
        log.info("Request: {} {} from {}", method, path, remoteAddress);

        // 记录请求头（排除敏感信息）
        if (log.isDebugEnabled()) {
            StringBuilder headers = new StringBuilder("Request Headers: ");
            request.getHeaders().forEach((name, values) -> {
                if (!SENSITIVE_HEADERS.contains(name)) {
                    headers.append(name).append("=").append(values).append(", ");
                } else {
                    headers.append(name).append("=***, ");
                }
            });
            log.debug(headers.toString());
        }

        // 在响应处理完成后记录日志
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            long duration = System.currentTimeMillis() - startTime;
            int statusCode = exchange.getResponse().getStatusCode() != null
                    ? exchange.getResponse().getStatusCode().value()
                    : 0;

            log.info("Response: {} {} {} - {} ms", method, path, statusCode, duration);
        }));
    }

    @Override
    public int getOrder() {
        // 在JWT过滤器之后执行
        return -90;
    }
}